package com.smart.community.commons.config.sender.impl;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.smart.community.commons.config.sender.LogSender;
import com.smart.community.commons.dto.ApiLogDTO;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@ConditionalOnProperty(name = "rocketmq.enabled", havingValue = "true", matchIfMissing = false)
public class RocketMQLogSender implements LogSender {
	@Value("${rocketmq.producer.group:sc-system-log-group}")
	private String producerGroup;

	@Value("${rocketmq.name-server:127.0.0.1:9876}")
	private String nameServer;

	@Value("${rocketmq.log.topic:sc_system_log_topic}") // 日志主题
	private String logTopic;

	private DefaultMQProducer producer;

	// 初始化生产者
	@PostConstruct
	public void init() throws Exception {
		try {
			producer = new DefaultMQProducer(producerGroup);
			producer.setNamesrvAddr(nameServer);
			producer.setSendMsgTimeout(10000); // 增加超时时间到10秒
			producer.setRetryTimesWhenSendFailed(2); // 发送失败重试次数
			producer.setRetryTimesWhenSendAsyncFailed(2); // 异步发送失败重试次数
			producer.setCompressMsgBodyOverHowmuch(4096); // 消息压缩阈值
			producer.setMaxMessageSize(4194304); // 最大消息大小4MB
			producer.start();
			log.info("RocketMQ生产者启动成功 - NameServer: {}, ProducerGroup: {}, Topic: {}", 
				nameServer, producerGroup, logTopic);
		} catch (Exception e) {
			log.error("RocketMQ生产者启动失败: {}", e.getMessage(), e);
			// 不抛出异常，避免影响应用启动
		}
	}

	@Override
	public void sendLog(ApiLogDTO logDTO) {
		if (producer == null) {
			log.warn("RocketMQ生产者未初始化，跳过日志发送");
			return;
		}
		
		try {
			// 转换DTO为JSON消息体
			String json = JSON.toJSONString(logDTO);
			Message message = new Message(logTopic, // 主题
					"system-log-tag", // 标签（用于过滤，监听者可以只接收此标签的消息）
					json.getBytes() // 消息体
			);
			
			// 异步发送消息，避免阻塞主流程
			producer.send(message, new SendCallback() {
				@Override
				public void onSuccess(SendResult sendResult) {
					log.debug("操作日志发送成功: {}", sendResult);
				}

				@Override
				public void onException(Throwable e) {
					log.error("操作日志发送失败: {}", e.getMessage(), e);
				}
			});
			
		} catch (Exception e) {
			log.error("发送操作日志失败: {}", e.getMessage(), e);
			// 不抛出异常，避免影响主业务流程
		}
	}

	// 销毁生产者
	@PreDestroy
	public void destroy() {
		if (producer != null) {
			try {
				producer.shutdown();
				log.info("RocketMQ生产者已关闭");
			} catch (Exception e) {
				log.error("关闭RocketMQ生产者失败: {}", e.getMessage(), e);
			}
		}
	}
}
